home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Best of Shareware
/
Best of PC Windows Shareware 1.0 - Wayzata Technology (7111) (1993).iso
/
mac
/
ZIPPED
/
DOS
/
PROGRAMG
/
FORTHCMP.ZIP
/
TAIL.4TH
< prev
next >
Wrap
Text File
|
1992-03-30
|
5KB
|
193 lines
\ TAIL PROGRAM, BY TOM ALMY.
\ THIS PROGRAM IS COPYRIGHT (C) 1985 BY TOM ALMY,
\ ALL RIGHTS RESERVED.
\ Users of ForthCMP are given permission to use or distribute this
\ program, as long as no charge is made and the credit message is maintained.
100 MSDOS
HEX 1000 DECIMAL CONSTANT BUFSIZ
INCLUDE FILTER
\ DATA DECLARATIONS
0 CONSTANT FALSE
-1 CONSTANT TRUE
CONTROL J CONSTANT NL \ line delimiter character
VARIABLE +FLAG \ flags in option string
VARIABLE CFLAG
VARIABLE RFLAG
2VARIABLE LCOUNT
2VARIABLE OFFSET \ Offset into file of pointer
VARIABLE RLINEBUF \ reverse line buffer
\ MESSAGES
0 0 IN/OUT
: NOTICE CONSOLE
." TAIL PRINTING PROGRAM " CR
." COPYRIGHT (C) 1985 BY THOMAS ALMY " CR ;
0 0 IN/OUT
: USAGE CONSOLE CR
." USAGE: TAIL [-[+][n][C][R]] [srcfile] [destfile]" CR
." where srcfile is an ascii source file, or - for standard input" CR
." and destfile is output file." CR
." + --> type leading lines instead of tail" CR
." n --> line count (default to 10)" CR
." C --> `n' is character count" CR
." R --> output lines backwards (+ or C ignored)" CR
ABORT ;
0 1 IN/OUT
: MORE-LINES? ( -- true if more lines )
LCOUNT 2@ 2DUP OR -ROT -1. D+ LCOUNT 2! ;
1 0 IN/OUT
: ?DIE IF CONSOLE ." I/O ERROR" ABORT THEN ;
\ routines for reverse reading
0 1 IN/OUT
: BACKREAD ( -- bofflag )
OFFSET 2@ OR 0= IF TRUE EXIT THEN ( backed up to start already )
OFFSET 2@ BUFSIZ 0 D- OFFSET 2!
infile OFFSET 2@ 0 FSEEK 2DROP ( back file up )
infile inbuffer @ BUFSIZ FREAD DUP BUFSIZ <> ?DIE
inbuffer @ + DUP inbufend ! inbufptr ! ( start at end of buffer )
FALSE
;
0 0 IN/OUT
: INIT-REVERSE
infile 0 0 2 FSEEK OFFSET 2! ( compute file size )
OFFSET 2+ @ BUFSIZ 1- AND ?DUP IF ( short first buffer? )
DUP NEGATE OFFSET 2+ +! ( adjust offset )
infile OFFSET 2@ 0 FSEEK 2DROP
infile inbuffer @ 2 PICK FREAD TUCK <> ?DIE
inbuffer @ + DUP inbufend ! inbufptr !
ELSE
inbuffer @ inbufptr !
BACKREAD DROP
THEN ;
0 1 IN/OUT
: -KEY ( -- key or -1 if BOF )
inbuffer @ inbufptr @ = IF BACKREAD IF TRUE EXIT THEN THEN
-1 inbufptr +!
inbufptr @ C@ ;
\ Copying routines
0 0 IN/OUT
: +COPY \ Copy in forward direction
CFLAG @ IF ( by character )
BEGIN
MORE-LINES? WHILE ( non-zero so move a character )
KEY DUP 0< NOT IF EMIT ELSE DROP EXIT THEN
REPEAT
ELSE ( by line )
BEGIN
MORE-LINES? WHILE ( non-zero so move a line )
BEGIN KEY DUP 0< IF DROP EXIT THEN
DUP NL <> WHILE
EMIT
REPEAT EMIT
REPEAT THEN ;
0 0 IN/OUT
: RCOPY \ Reverse copy
2 ALLOT
HERE RLINEBUF !
256 ALLOT ( allot our storage )
INIT-REVERSE ( will go backwards )
-KEY 0< IF EXIT THEN ( quit if nothing )
BEGIN MORE-LINES? WHILE RLINEBUF @ ( end of line )
BEGIN -KEY DUP 0< NOT OVER NL <> AND WHILE
OVER C! 1+ REPEAT ( buffer, key ) SWAP
BEGIN DUP RLINEBUF @ <> WHILE
1- DUP C@ EMIT
REPEAT DROP
NL EMIT
TRUE = IF EXIT THEN
REPEAT ;
0 0 IN/OUT
: BACK-LINES \ Search backwards from end by lines
INIT-REVERSE
BEGIN BEGIN -KEY DUP 0< IF DROP EXIT THEN
NL = UNTIL
MORE-LINES? 0= UNTIL
KEY DROP ;
0 0 IN/OUT
: BACK-CHARS \ Tricky search backwards by characters
infile 0 0 2 FSEEK LCOUNT 2@ DMIN DNEGATE
infile -ROT 1 FSEEK 2DROP ;
0 0 IN/OUT
: -COPY \ Copy final lines/characters
CFLAG @ IF BACK-CHARS ELSE BACK-LINES THEN
BEGIN KEY DUP 0< NOT WHILE
EMIT REPEAT DROP ;
\ Parse Command stream
1 0 IN/OUT
: BAD-OPTION \ Just print the error message then quit
CONSOLE CR ." BAD OPTION - " EMIT USAGE ;
0 0 IN/OUT
: READ-OPTIONS
+FLAG OFF
CFLAG OFF
RFLAG OFF
10. LCOUNT 2!
OPTIONSTRING 2@ 0 ?DO COUNT
DUP ASCII a >= IF BL - THEN CASE
ASCII C OF CFLAG ON 1 ENDOF
ASCII + OF +FLAG ON 1 ENDOF
ASCII R OF RFLAG ON 1 ENDOF
DUP ASCII 0 >= OVER ASCII 9 <= AND IF
DROP DUP >R 2- 0. ROT CONVERT -ROT LCOUNT 2! DUP R> - 1+ 0
ELSE BAD-OPTION THEN ENDCASE
+LOOP DROP ;
1 1 IN/OUT
CODE SERIAL? ( handle -- TRUE if serial device )
HEX
AX BX MOV
4400 # AX MOV
21 INT
DX AX MOV
80 # AX AND
RET
END-CODE
\ MAIN ROUTINE
: MAIN
SETBUFS
NOTICE
SETFILES infile HCB>H SERIAL? OR IF USAGE THEN
READ-OPTIONS
RFLAG @ IF
RCOPY
ELSE
+FLAG @ IF
+COPY
ELSE
-COPY
THEN
THEN
BYE ;
INCLUDE DOS2
INCLUDE FORTHLIB
END